const { ObjectID } = require('mongodb')
const { models } = require('../model')

let cacheTags = []
let cacheTagsTime = new Date()

async function refreshTagCache () {
  cacheTags = await models.ToolTag.find({}).project({
    name: 1,
    level: 1,
    color: 1
  }).toArray()
  cacheTagsTime = new Date()
}

async function getTagByIds (tagIds) {
  // 缓存有效期 60S
  if (new Date() - cacheTagsTime > 60 * 1000) {
    await refreshTagCache()
  }
  const unmatchedCacheIds = tagIds.filter(id => !cacheTags.find(e => e._id.equals(id)))
  if (unmatchedCacheIds.length > 0) {
    await refreshTagCache()
  }
  // 缓存过期
  return tagIds.map(id => {
    return cacheTags.find(e => e._id.equals(id))
  })
}

async function incStatistics ({ id, statistics }) {
  const inc = {}
  Object.keys(statistics).forEach(key => {
    inc[`statistics.${key}`] = statistics[key]
  })
  const result = await models.Tool.updateById(id, { $inc: inc })
  if (result.matchedCount === 0) {
    throw new Error('无对应 ID 资源')
  }
}

async function updateById (id, update) {
  const oldTool = await models.Tool.findById(id)
  if (!update) {
    throw '无更新内容字段'
  }
  if (!oldTool) {
    throw '无对应 ID 资源'
  }
  const tool = update
  // 避免更新的字段
  delete tool.statistics
  delete tool.createdAt
  delete tool.updatedAt
  delete tool.source
  delete tool._id
  tool.tags = tool.tags.map(e => ObjectID(e))
  return await models.Tool.updateById(id, {
    $set: tool
  })
}

async function createTool (tool) {
  const formatTool = {
    tags: [],
    name: '',
    icon: '',
    description: '',
    permalink: '',

    score: 0,
    charge: {},
    resources: [],

    statistics: {
      likeCount: 0,
      clickCount: 0,
      showCount: 0,
      forwardCount: 0,
      collectionCount: 0
    },
    comments: [],

    source: {},

    createdAt: new Date(),
    updatedAt: new Date()
  }
  // 避免更新的字段
  tool.createdAt = new Date()
  delete tool._id
  tool.tags = tool.tags.map(e => ObjectID(e))
  return await models.Tool.insertOne({
    ...formatTool,
    ...tool
  })
}

module.exports = {
  getTagByIds,
  incStatistics,
  updateById,
  createTool
}
